package tl.study.jvm;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author <a href="eric_zheng@lanzuo.com.cn">eric</a>
 * @date 2022/8/16
 * @description 自定义类加载器
 */
public class CustomClassLoader {

    static class SpiritClassLoader extends ClassLoader {
        static final String SPIRIT_ClASS_LOADER_PATH = "D:/面试/jvm_class";

        private byte[] loadByte(String name) throws IOException {
            name = name.replaceAll("\\.", "/");
            FileInputStream fis = new FileInputStream(SPIRIT_ClASS_LOADER_PATH + "/" + name + ".class");
            int len = fis.available();
            byte[] data = new byte[len];
            fis.read(data);
            fis.close();
            return data;
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] data = loadByte(name);
                return defineClass(name, data, 0, data.length);
            } catch (IOException e) {
                e.printStackTrace();
                throw new ClassNotFoundException();
            }
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        SpiritClassLoader spiritClassLoader = new SpiritClassLoader();
        // 将classpath中的jvmTestUser.class，移动到D:/面试/jvm_class下，使得这个类在applicationClassLoader中无法加载，从而通过我们自定义的类加载器来加载数据
        Class jvmTestUserClass = spiritClassLoader.loadClass("tl.study.jvm.JvmTestUser");
        Object jvmTestUser = jvmTestUserClass.newInstance();

        Method method = jvmTestUserClass.getDeclaredMethod("say", null);
        method.invoke(jvmTestUser, null);
        System.out.println(jvmTestUserClass.getClassLoader());
    }
}
